﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Tools;

namespace Pixysoft.Framework.Sockets.Core
{
    /// <summary>
    /// 单socket性能检测器
    /// </summary>
    class PerformanceAnalyzer : IPerformanceAnalyzer
    {
        string identifier = null;

        int currentRequestHeader = -1;
        int formerRequestHeader = -1;

        int requestTimes = 0;
        double requestInterval = -1;
        DateTime createDate = GlobalTimer.Instance.GetGlobalTime();
        DateTime currentRequestTime = DateTime.MinValue;
        DateTime formerRequestTime = DateTime.MinValue;
        int errorTimes = 0;

        public PerformanceAnalyzer(string identifier)
        {
            this.identifier = identifier;
            this.createDate = GlobalTimer.Instance.GetGlobalTime();
        }

        public double OnRequestArrived(int protocol)
        {
            this.formerRequestHeader = this.currentRequestHeader;
            this.currentRequestHeader = protocol;

            return OnRequestArrived();
        }

        public double OnRequestArrived()
        {
            DateTime requestTime = GlobalTimer.Instance.GetGlobalTime();

            if (this.currentRequestTime == DateTime.MinValue
                    || this.formerRequestTime == DateTime.MinValue)
            {
                this.formerRequestTime = requestTime;

                this.currentRequestTime = requestTime;

                requestTimes++;

                return -1;
            }

            TimeSpan reqSpan = requestTime - currentRequestTime;

            long interval = reqSpan.Milliseconds;

            formerRequestTime = currentRequestTime;

            currentRequestTime = requestTime;

            if (this.requestInterval < 0)
                this.requestInterval = interval;

            double nRequestInterval = (this.requestInterval * this.requestTimes + interval) / (this.requestTimes + 1);

            this.requestInterval = nRequestInterval;

            this.requestTimes++;

            return this.requestInterval;
        }

        public bool DoNonDuplicateRequest()
        {
            if (formerRequestHeader != currentRequestHeader)
                return true;

            //如果上次时间+间隔大于当前时间，表示频率过大

            if (formerRequestTime.AddMilliseconds(SettingHelper.default_interval_command_nonduplicate) > GlobalTimer.Instance.GetGlobalTime())
                return false;

            return true;
        }

        public bool DoDuplicateRequest()
        {
            if (formerRequestHeader != currentRequestHeader)
            {
                return true;
            }

            //如果上次时间+间隔大于当前时间，表示频率过大

            if (formerRequestTime.AddMilliseconds(SettingHelper.default_interval_command_duplicate) > GlobalTimer.Instance.GetGlobalTime())
                return false;

            return true;
        }

        public int DoError()
        {
            this.errorTimes++;
            return this.errorTimes;
        }

        public bool IsTimeout()
        {
            if (currentRequestTime == DateTime.MinValue)
                return false;

            return currentRequestTime.AddMilliseconds(SettingHelper.default_timeout_connection) < GlobalTimer.Instance.GetGlobalTime();
        }

        public bool IsHighFrequency()
        {
            if (this.requestInterval < 0)
                return false;

            return this.requestInterval < SettingHelper.default_max_socket_frequency;
        }

        public bool IsMaxError()
        {
            return this.errorTimes >= SettingHelper.default_max_socket_error;
        }


        public double RequestInterval
        {
            get
            {
                return requestInterval;
            }
        }

        public int ErrorTimes
        {
            get
            {
                return errorTimes;
            }
        }

        public int RequestTimes
        {
            get
            {
                return requestTimes;
            }
        }

        public DateTime CreateDate
        {
            get
            {
                return createDate;
            }
        }

        public void Dispose()
        {

        }

    }
}
